﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using GraphDrawer.GraphProvider;

namespace GraphDrawer
{
    public partial class ModelEditor : UserControl
    {
        private double ParentHeight = 250.0;
        private double ParentWidth = 200.0;

        private Boolean isMouseCaptured = false;
        private double mouseVerticalPosition;
        private double mouseHorizontalPosition;

        private Boolean isDrawingConnection = false;
        private double StartMouseVerticalPosition;
        private double StartMouseHorizontalPosition;

        private Connector lastConector;
        private ModelEdge lineCanvas;
        private ModelNode StartNode;
        private Canvas SelectedElement;
        private Brush normalBrush = new SolidColorBrush(Colors.Black);
        private Brush highlightedBrush = new SolidColorBrush(Colors.Yellow);

        private GraphProvider.DiseaseModelGraph graph = new GraphDrawer.GraphProvider.DiseaseModelGraph();
        private GraphProvider.SimpleDiseaseModelEdge lastEdge;
        public String GraphML;

        public String StartState = String.Empty;


        public ModelEditor()
        {
            InitializeComponent();
            popup.Closed += new RoutedEventHandler(popup_Closed);
            popup.OK += new RoutedEventHandler(popup_OK);
            edgePopUp.OK += new RoutedEventHandler(edge_OK);
            edgePopUp.Closed += new RoutedEventHandler(edge_Closed);
			export.Closed += new RoutedEventHandler(export_Closed);
			export.OK += new RoutedEventHandler(export_OK);
            App.Current.Host.Content.IsFullScreen = false;
            Menu.graphProvider.GetDiseaseModelStateNamesCompleted += new EventHandler<GetDiseaseModelStateNamesCompletedEventArgs>(graphProvider_GetDiseaseModelStateNamesCompleted);
            Menu.graphProvider.GetDiseaseModelStateNamesAsync();
        }

        void graphProvider_GetDiseaseModelStateNamesCompleted(object sender, GetDiseaseModelStateNamesCompletedEventArgs e)
        {
            foreach (var item in e.Result)
            {
                popup.ComboBoxStateNames.Items.Add(item);
            }
            popup.ComboBoxStateNames.SelectedIndex = 0;
        }

        public String CreateGraphML()
        {
            
            GraphML.graphml g = new GraphDrawer.GraphML.graphml();
            g.key = new GraphDrawer.GraphML.graphmlKey[4];
            g.key[0] = new GraphDrawer.GraphML.graphmlKey();
            g.key[0].id = "stateName";
            g.key[0].@for = "node";
            g.key[0].attrname = "stateName";
            g.key[0].attrtype = "string";
            
            g.key[1] = new GraphDrawer.GraphML.graphmlKey();
            g.key[1].id = "stateClass";
            g.key[1].@for = "node";
            g.key[1].attrname = "stateClass";
            g.key[1].attrtype = "string";

            g.key[2] = new GraphDrawer.GraphML.graphmlKey();
            g.key[2].id = "nodeColor";
            g.key[2].@for = "node";
            g.key[2].attrname = "nodeColor";
            g.key[2].attrtype = "string";

            g.key[3] = new GraphDrawer.GraphML.graphmlKey();
            g.key[3].id = "probability";
            g.key[3].@for = "edge";
            g.key[3].attrname = "probability";
            g.key[3].attrtype = "double";

            g.graph = new GraphDrawer.GraphML.graphmlGraph();
            g.graph.id = "G";
            g.graph.parseorder = "nodesfirst";
            g.graph.parseedgeids = "free";
            g.graph.parsenodeids = "free";
            g.graph.edgedefault = "directed";

            g.graph.parseedges = graph.Edges.Count;
            g.graph.parsenodes = graph.Vertices.Count;

            g.graph.node = new GraphDrawer.GraphML.graphmlGraphNode[g.graph.parsenodes];
            g.graph.edge = new GraphDrawer.GraphML.graphmlGraphEdge[g.graph.parseedges];

            for (int i = 0; i < graph.Vertices.Count; i++)
            {
                var node = new GraphDrawer.GraphML.graphmlGraphNode();

                node.id = graph.Vertices[i].stateName;


                List<GraphDrawer.GraphML.graphmlGraphNodeData> datas = new List<GraphDrawer.GraphML.graphmlGraphNodeData>();
                foreach (var item in g.key)
                {
                    if (item.@for == "node")
                    {
                        var data = new GraphDrawer.GraphML.graphmlGraphNodeData();
                        data.key = item.attrname;
                        data.Value = graph.Vertices[i].GetType().GetProperty(item.attrname).GetValue(graph.Vertices[i], null).ToString();
                        datas.Add(data);
                    }
                }

                node.data = datas.ToArray();
                g.graph.node[i] = node;
            }

            for (int i = 0; i < graph.Edges.Count; i++)
            {
                var edge = new GraphDrawer.GraphML.graphmlGraphEdge();

                SilverLightDiseaseModelNode source = null;
                SilverLightDiseaseModelNode target = null;

                foreach (var item in graph.Vertices)
                {
                    if (item.Id == graph.Edges[i].Source)
                    {
                        source = item;
                    }
                    if (item.Id == graph.Edges[i].Target)
                    {
                        target = item;
                    }

                    if (source != null & target != null)
                        break;
                }

                edge.id = source.stateName + "->" + target.stateName;
                edge.source = source.stateName;
                edge.target = target.stateName;


                List<GraphDrawer.GraphML.graphmlGraphEdgeData> datas = new List<GraphDrawer.GraphML.graphmlGraphEdgeData>();
                foreach (var item in g.key)
                {
                    if (item.@for == "edge")
                    {
                        var data = new GraphDrawer.GraphML.graphmlGraphEdgeData();
                        data.key = item.attrname;
                        data.Value = graph.Edges[i].GetType().GetProperty(item.attrname).GetValue(graph.Edges[i], null).ToString();
                        datas.Add(data);
                    }
                }

                edge.data = datas.ToArray();
                g.graph.edge[i] = edge;
            }

            System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(g.GetType());
            System.IO.StringWriter writer = new System.IO.StringWriter();
            ser.Serialize(writer, g);

            return writer.ToString();
        }

        #region PopUps events
        #region Edge PopUp
        void edge_Closed(object sender, RoutedEventArgs e)
        {
            lastEdge = null;
            lastConector = null;
            lineCanvas = null;
        }

        void edge_OK(object sender, RoutedEventArgs e)
        {
            lastEdge = new SimpleDiseaseModelEdge();

            lastEdge.probability = edgePopUp.Probability;
            lastEdge.Source = StartNode.node.Id;
            lastEdge.Target = ((ModelNode)lastConector.Parent).node.Id;
            if (graph.Edges == null)
                graph.Edges = new System.Collections.ObjectModel.ObservableCollection<SimpleDiseaseModelEdge>();
            graph.Edges.Add(lastEdge);

            lineCanvas.edge = lastEdge;

            lastEdge = null;
            lastConector = null;
            lineCanvas = null;
        }
        #endregion

        #region Node PopUp
        void popup_OK(object sender, RoutedEventArgs e)
        {
            //TODO: show question about probability and Name                     
            int selectorHeight = 5;
            int selectorWidth = 5;

            Canvas RectWithTitle = CreateRectangleWithTitle(popup.NodeName, popup.NodeColor);
            Canvas selectorCanvasLeft = CreateConnector(selectorHeight, selectorWidth);
            Canvas selectorCanvasRight = CreateConnector(selectorHeight, selectorWidth);
            Canvas selectorCanvasTop = CreateConnector(selectorHeight, selectorWidth);
            Canvas selectorCanvasBootom = CreateConnector(selectorHeight, selectorWidth);

            RectWithTitle.SetValue(Canvas.LeftProperty, selectorCanvasLeft.Width / 2.0);
            RectWithTitle.SetValue(Canvas.TopProperty, selectorCanvasLeft.Height / 2.0);

            selectorCanvasLeft.SetValue(Canvas.LeftProperty, 0.0);
            selectorCanvasLeft.SetValue(Canvas.TopProperty, RectWithTitle.Height / 2.0);

            selectorCanvasRight.SetValue(Canvas.LeftProperty, RectWithTitle.Width);
            selectorCanvasRight.SetValue(Canvas.TopProperty, RectWithTitle.Height / 2.0);

            selectorCanvasTop.SetValue(Canvas.LeftProperty, RectWithTitle.Width / 2.0);
            selectorCanvasTop.SetValue(Canvas.TopProperty, 0.0);

            selectorCanvasBootom.SetValue(Canvas.LeftProperty, RectWithTitle.Width / 2.0);
            selectorCanvasBootom.SetValue(Canvas.TopProperty, RectWithTitle.Height);

            ModelNode element = new ModelNode()
            {
                Width = RectWithTitle.Width + selectorWidth,
                Height = RectWithTitle.Height + selectorHeight
            };

            element.border = RectWithTitle.Children[0] as Rectangle;

            element.MouseLeftButtonDown += new MouseButtonEventHandler(Handle_MouseDown);
            element.MouseLeftButtonUp += new MouseButtonEventHandler(Handle_MouseUp);
            element.MouseMove += new MouseEventHandler(Handle_MouseMove);

            element.Children.Add(RectWithTitle);
            element.Children.Add(selectorCanvasLeft);
            element.Children.Add(selectorCanvasRight);
            element.Children.Add(selectorCanvasTop);
            element.Children.Add(selectorCanvasBootom);

            element.connectors.Add(selectorCanvasLeft as Connector);
            element.connectors.Add(selectorCanvasRight as Connector);
            element.connectors.Add(selectorCanvasTop as Connector);
            element.connectors.Add(selectorCanvasBootom as Connector);

            element.SetValue(Canvas.LeftProperty, ParentWidth / 2.0 - element.Width);
            element.SetValue(Canvas.TopProperty, ParentHeight / 2.0 - element.Height);


            var node = new SilverLightDiseaseModelNode();
            node.Id = node.GetHashCode();
            node.stateName = popup.NodeName;
            node.stateClass = popup.StateClass;
            node.nodeColor = popup.NodeColor.ToString();
            if (graph.Vertices == null)
                graph.Vertices = new System.Collections.ObjectModel.ObservableCollection<SilverLightDiseaseModelNode>();
            graph.Vertices.Add(node);

            element.node = node;

            if (popup.StartState.IsChecked.HasValue)
            {
                if(popup.StartState.IsChecked.Value)
                    StartState = popup.NodeName;
            }

            rootCanvas.Children.Add(element);
        }

        void popup_Closed(object sender, RoutedEventArgs e)
        {

        }
        #endregion
        #endregion

		#region Export PopUp
		void export_OK(object sender, RoutedEventArgs e) {
			
		}

		void export_Closed(object sender, RoutedEventArgs e) {
			
		}
		#endregion

        #region Selector Events
        void selectorCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            lastConector.ReleaseMouseCapture();

            Boolean isOnConnector = false;

            foreach (var item in rootCanvas.Children)
            {
                if (item is ModelNode)
                {
                    ModelNode model = item as ModelNode;
                    foreach (var connectorTOCheck in model.connectors)
                    {
                        Point p = e.GetPosition(connectorTOCheck);
                        double x1 = 0;
                        double x2 = connectorTOCheck.Width;
                        double y1 = 0;
                        double y2 = connectorTOCheck.Height;

                        if ((p.X >= x1 && p.X <= x2) &&
                            (p.Y >= y1 && p.Y <= y2))
                        {
                            isOnConnector = true;
                            connectorTOCheck.lines.Add(lineCanvas, true);
                            lastConector = connectorTOCheck;
                            edgePopUp.Height = App.Current.Host.Content.ActualHeight;
                            edgePopUp.Width = App.Current.Host.Content.ActualWidth;
                            edgePopUp.SetValue(Canvas.ZIndexProperty, 15);
                            edgePopUp.Visibility = Visibility.Visible;

                            break;
                        }
                    }
                }
            }



            if (!isOnConnector)
            {
                rootCanvas.Children.Remove(lineCanvas);

                lastEdge = null;
                lastConector = null;
                lineCanvas = null;
            }

            mouseVerticalPosition = -1;
            mouseHorizontalPosition = -1;

            isDrawingConnection = false;

        }

        void selectorCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isMouseCaptured = false;
            isDrawingConnection = true;
            lastConector = sender as Connector;

            StartNode = lastConector.Parent as ModelNode;

            mouseVerticalPosition = e.GetPosition(rootCanvas).Y;
            mouseHorizontalPosition = e.GetPosition(rootCanvas).X;

            StartMouseVerticalPosition = e.GetPosition(this).Y;
            StartMouseHorizontalPosition = e.GetPosition(this).X;

            isMouseCaptured = true;
            lastConector.CaptureMouse();
        }

        void selectorCanvas_MouseLeave(object sender, MouseEventArgs e)
        {
            Canvas canvas = sender as Canvas;
            ScaleTransform t = new ScaleTransform();
            t.CenterX = canvas.Width / 2.0;
            t.CenterY = canvas.Height / 2.0;
            t.ScaleX = 1.0;
            t.ScaleY = 1.0;

            canvas.RenderTransform = t;
        }

        void selectorCanvas_MouseEnter(object sender, MouseEventArgs e)
        {
            Canvas canvas = sender as Canvas;

            ScaleTransform t = new ScaleTransform();
            t.CenterX = canvas.Width / 2.0;
            t.CenterY = canvas.Height / 2.0;
            t.ScaleX = 2.0;
            t.ScaleY = 2.0;

            canvas.RenderTransform = t;
        }
        #endregion

        #region Nodes events
        void Handle_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!isDrawingConnection)
            {
                ModelNode item = sender as ModelNode;

                RemoveHighlight();

                SelectedElement = item;
                ModelNode model = SelectedElement as ModelNode;
                model.border.Stroke = highlightedBrush;

                mouseVerticalPosition = e.GetPosition(null).Y;
                mouseHorizontalPosition = e.GetPosition(null).X;
                isMouseCaptured = true;
                item.CaptureMouse();
            }

        }

        void Handle_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (!isDrawingConnection)
            {
                Canvas item = sender as Canvas;
                isMouseCaptured = false;
                item.ReleaseMouseCapture();
                mouseVerticalPosition = -1;
                mouseHorizontalPosition = -1;
            }

        }

        void Handle_MouseMove(object sender, MouseEventArgs e)
        {
            Canvas item = sender as Canvas;
            if (isMouseCaptured && !isDrawingConnection)
            {

                // Calculate the current position of the object.
                double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
                double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
                double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
                double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);

                foreach (var child in item.Children)
                {
                    if (child is Connector)
                    {
                        Connector connector = child as Connector;
                        foreach (var pair in connector.lines)
                        {
                            var canvas = pair.Key;

                            canvas.Height += deltaV;
                            canvas.Width += deltaH;

                            Line line = canvas.line;

                            double x1 = (double)item.GetValue(Canvas.LeftProperty);
                            double x2 = x1 + item.Width;
                            double y1 = (double)item.GetValue(Canvas.TopProperty);
                            double y2 = y1 + item.Height;

                            if (pair.Value)
                            {
                                line.X2 += deltaH;
                                line.Y2 += deltaV;
                            }
                            else
                            {
                                line.X1 += deltaH;
                                line.Y1 += deltaV;
                            }

							StartMouseHorizontalPosition = line.X1;
							StartMouseVerticalPosition = line.Y1;
							mouseHorizontalPosition = line.X2;
							mouseVerticalPosition = line.Y2;
                            Point l1;
                            Point l2;
                            GetArrow(out l1, out l2);

							canvas.lineArrow.Points.Clear();
                            //TODO: arrow
                            canvas.lineArrow.Points.Add(new Point(mouseHorizontalPosition, mouseVerticalPosition));
                            canvas.lineArrow.Points.Add(new Point(l1.X, l1.Y));
                            canvas.lineArrow.Points.Add(new Point(l2.X, l2.Y));
                        }
                    }
                }

                // Set new position of object.
                item.SetValue(Canvas.TopProperty, newTop);
                item.SetValue(Canvas.LeftProperty, newLeft);

                // Update position global variables.
                mouseVerticalPosition = e.GetPosition(null).Y;
                mouseHorizontalPosition = e.GetPosition(null).X;
            }
            if (isDrawingConnection)
            {
                if (lineCanvas == null)
                {

                    var line = new Line
                    {
                        X1 = StartMouseHorizontalPosition,
                        Y1 = StartMouseVerticalPosition,
                        X2 = mouseHorizontalPosition,
                        Y2 = mouseVerticalPosition,
                        Stroke = new SolidColorBrush(Colors.Black),
                        StrokeThickness = 3
                    };
                   
                    

                    Polygon lineArrow = new Polygon();
                    lineArrow.Points = new PointCollection();
                    lineArrow.Fill = new SolidColorBrush(Colors.Black);
                    Point l1;
                    Point l2;
                    GetArrow(out l1, out l2);
                    
                    //TODO: arrow
                    lineArrow.Points.Add(new Point(mouseHorizontalPosition, mouseVerticalPosition));
                    lineArrow.Points.Add(new Point(l1.X, l1.Y));
                    lineArrow.Points.Add(new Point(l2.X, l2.Y));

                    lineCanvas = new ModelEdge() { Height = line.Height, Width = line.Width };

                    lineCanvas.MouseLeftButtonDown += new MouseButtonEventHandler(lineCanvas_MouseLeftButtonDown);

                    lineCanvas.line = line;
                    lineCanvas.lineArrow = lineArrow;

                    lineCanvas.Children.Add(line);
                    lineCanvas.Children.Add(lineArrow);
                    rootCanvas.Children.Add(lineCanvas);
                    
                    lastConector.lines.Add(lineCanvas, false);
                }
                else
                {
                    lineCanvas.line.X2 = mouseHorizontalPosition;
                    lineCanvas.line.Y2 = mouseVerticalPosition;                    

                    Point l1;
                    Point l2;
                    GetArrow(out l1, out l2);


                    lineCanvas.lineArrow.Points.Clear();
                    //TODO: arrow
                    lineCanvas.lineArrow.Points.Add(new Point(mouseHorizontalPosition, mouseVerticalPosition));
                    lineCanvas.lineArrow.Points.Add(new Point(l1.X, l1.Y));
                    lineCanvas.lineArrow.Points.Add(new Point(l2.X, l2.Y));
 
                    lineCanvas.Height = lineCanvas.line.Height;
                    lineCanvas.Width = lineCanvas.line.Width;                                       
                }

                mouseVerticalPosition = e.GetPosition(rootCanvas).Y;
                mouseHorizontalPosition = e.GetPosition(rootCanvas).X;


            }
        }

        private void GetArrow(out Point p1, out Point p2)
        {
            RotateTransform rot1 = new RotateTransform();
            rot1.Angle = 45.0;
            rot1.CenterX = mouseHorizontalPosition;
            rot1.CenterY = mouseVerticalPosition;

            RotateTransform rot2 = new RotateTransform();
            rot2.Angle = -45.0;
            rot2.CenterX = mouseHorizontalPosition;
            rot2.CenterY = mouseVerticalPosition;

                        
            //ScaleTransform scl = new ScaleTransform();
            //TODO: set const scale :P
            //scl.ScaleX = 0.2;
            //scl.ScaleY = 0.2;
            //scl.CenterX = mouseHorizontalPosition;
            //scl.CenterY = mouseVerticalPosition;            

            //p1 = rot1.Transform(new Point(StartMouseHorizontalPosition, StartMouseVerticalPosition));
            //p2 = rot2.Transform(new Point(StartMouseHorizontalPosition, StartMouseVerticalPosition));

            //p1 = scl.Transform(p1);
            //p2 = scl.Transform(p2);
			
			// Const size of the arrow
			double px = StartMouseHorizontalPosition - mouseHorizontalPosition;
			double py = StartMouseVerticalPosition - mouseVerticalPosition;
			double d = Math.Sqrt(px * px + py * py);
			px /= d;
			py /= d;
			p1 = rot1.Transform(new Point(mouseHorizontalPosition + 15 * px, mouseVerticalPosition + 15 * py));
			p2 = rot2.Transform(new Point(mouseHorizontalPosition + 15 * px, mouseVerticalPosition + 15 * py));
        }
        #endregion

        void lineCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Canvas item = sender as Canvas;
            RemoveHighlight();
            SelectedElement = item;
            Line line = item.Children[0] as Line;
            line.Stroke = highlightedBrush;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (!String.IsNullOrEmpty(StartState))
            {
                popup.StartState.IsChecked = false;
            }
            
            popup.Height = App.Current.Host.Content.ActualHeight;
            popup.Width = App.Current.Host.Content.ActualWidth;
            GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
            Point offset = gt.Transform(new Point(0, 0)); 
            
            popup.SetValue(Canvas.TopProperty, -offset.Y);
            popup.SetValue(Canvas.LeftProperty, -offset.X);
            popup.SetValue(Canvas.ZIndexProperty, 15);
            popup.Visibility = Visibility.Visible;
        }

        private void RemoveElement_Click(object sender, RoutedEventArgs e)
        {
            if (SelectedElement is ModelNode)
            {
                var model = SelectedElement as ModelNode;
                List<ModelEdge> toRemove = new List<ModelEdge>();
                foreach (var item in graph.Edges)
                {
                    Boolean remove = false; 

                    if (item.Source == model.node.Id)
                    {
                        remove = true;
                    }

                    if (item.Target == model.node.Id)
                    {
                        remove = true;
                    }

                    if (remove)
                    {
                        
                        foreach (var elem in rootCanvas.Children)
                        {
                            if (elem is ModelEdge)
                            {
                                var edge = elem as ModelEdge;
                                if (edge.edge == item && !toRemove.Contains(edge))
                                {
                                    toRemove.Add(edge);
                                }
                            }
                        }

                        
                    }
                }

                foreach (var elem in toRemove)
                {
                    RemoveLine(elem);
                }

                graph.Vertices.Remove(model.node);
                rootCanvas.Children.Remove(model);
            }
            if (SelectedElement is ModelEdge)
            {
                //Line
                var canvas = SelectedElement as ModelEdge;
                RemoveLine(canvas);
            }
        }

        private void RemoveLine(ModelEdge canvas)
        {
            var line = canvas.line;

            rootCanvas.Children.Remove(canvas);

            foreach (var item in rootCanvas.Children)
            {
                if (item is ModelNode)
                {
                    ModelNode model = item as ModelNode;
                    foreach (var connectorTOCheck in model.connectors)
                    {
                        connectorTOCheck.lines.Remove(canvas);
                    }
                }
            }

            graph.Edges.Remove(canvas.edge);
        }

        private Connector CreateConnector(int selectorHeight, int selectorWidth)
        {
            Connector selectorCanvas = new Connector() { Height = selectorHeight, Width = selectorWidth };
            Border selectorBorder = new Border()
            {
                Width = selectorWidth,
                Height = selectorHeight,
                BorderThickness = new Thickness(1),
                BorderBrush = new SolidColorBrush(Colors.Black)
            };
            Line selectorHorizontalLine = new Line()
            {
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 1.0,
                X1 = 1.0,
                X2 = selectorHeight - 1.0,
                Y1 = selectorWidth / 2.0,
                Y2 = selectorWidth / 2
            };

            Line selectorVerticallLine = new Line()
            {
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 1.0,
                X1 = selectorHeight / 2.0,
                X2 = selectorHeight / 2.0,
                Y1 = 1.0,
                Y2 = selectorWidth - 1.0
            };
            selectorCanvas.Children.Add(selectorBorder);
            selectorCanvas.Children.Add(selectorHorizontalLine);
            selectorCanvas.Children.Add(selectorVerticallLine);

            selectorCanvas.MouseLeftButtonDown += new MouseButtonEventHandler(selectorCanvas_MouseLeftButtonDown);
            selectorCanvas.MouseLeftButtonUp += new MouseButtonEventHandler(selectorCanvas_MouseLeftButtonUp);
            selectorCanvas.MouseEnter += new MouseEventHandler(selectorCanvas_MouseEnter);
            selectorCanvas.MouseLeave += new MouseEventHandler(selectorCanvas_MouseLeave);

            return selectorCanvas;
        }

        private Canvas CreateRectangleWithTitle(String name, Color color)
        {
            LinearGradientBrush myHorizontalGradient = GetGradient(color);
            Brush projBrush = myHorizontalGradient;

            Brush textColor = new SolidColorBrush(Colors.Black);
            TextBlock title = new TextBlock() { Foreground = textColor, Text = name, FontSize = 12 };

            double Height = 25d;
            double Width = (title.ActualWidth + 4) < Height ? Height : title.ActualWidth + 4;
            Width += 4;

            Canvas RectWithTitle = new Canvas() { Width = Width, Height = Height };

            Rectangle nodeBkg = new Rectangle()
            {
                Width = Width,
                Height = Height,
                Fill = projBrush,
                Stroke = normalBrush
            };

            nodeBkg.RadiusX = 10;
            nodeBkg.RadiusY = 10;

            RectWithTitle.Children.Add(nodeBkg);
            RectWithTitle.Children.Add(title);

            double left = (nodeBkg.Width - title.ActualWidth) / 2;
            double top = (nodeBkg.Height - title.ActualHeight) / 2;
            title.SetValue(Canvas.LeftProperty, left);
            title.SetValue(Canvas.TopProperty, top);

            return RectWithTitle;
        }

        private static LinearGradientBrush GetGradient(Color second)
        {
            GradientStopCollection GradientStops = new GradientStopCollection();
            LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();
            myHorizontalGradient.StartPoint = new Point(0.5, 0);
            myHorizontalGradient.EndPoint = new Point(0.5, 1);
            myHorizontalGradient.GradientStops.Add(new GradientStop() { Color = second, Offset = 1.0 });
            myHorizontalGradient.GradientStops.Add(new GradientStop() { Color = Colors.White, Offset = 0.1 });
            return myHorizontalGradient;
        }

        private void RemoveHighlight()
        {
            if (SelectedElement != null)
            {
                if (SelectedElement is ModelNode)
                {
                    ModelNode model = SelectedElement as ModelNode;
                    model.border.Stroke = normalBrush;
                }
                if (SelectedElement is ModelEdge)
                {
                    //LIne
                    ModelEdge item = SelectedElement as ModelEdge;
                    Line line = item.line;
                    line.Stroke = normalBrush;
                }
            }
        }

        private void Save_Click(object sender, RoutedEventArgs e)
        {
            GraphML = CreateGraphML();
            exportToDatabase.IsEnabled = true;
            Menu.PopUp.btnOk.IsEnabled = true;
        }

		private void ExportToDatabase_Click(object sender, RoutedEventArgs e) {
			export.Height = App.Current.Host.Content.ActualHeight;
			export.Width = App.Current.Host.Content.ActualWidth;
			GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
			Point offset = gt.Transform(new Point(0, 0));

			export.SetValue(Canvas.TopProperty, -offset.Y);
			export.SetValue(Canvas.LeftProperty, -offset.X);
			export.SetValue(Canvas.ZIndexProperty, 15);
			export.Visibility = Visibility.Visible;
		}
    }
}